;;;; This file includes custom functions to add some
;;;;    functionality to Emacs, like movement and
;;;;    refreshing the compile command.

;;; Movement functions

(defun custom/copy-whole-line (arg)
  "Put a whole line in the kill ring."
  (interactive "p")
  (kill-whole-line 0)
  (yank))

(defun custom/newline-below()
  "Open a new line below the current line, no matter the position of the cursor."
  (interactive)
  (end-of-line)
  (newline)
  (indent-for-tab-command))

(defun custom/newline-above()
  "Open a new line above the current line, no matter the position of the cursor."
  (interactive)
  (beginning-of-line)
  (newline)
  (forward-line -1)
  (indent-for-tab-command))

(defun custom/move-line (arg)
  "Move a line arg times up or down"
  (when (or (> arg 0) (not (bobp)))
    (forward-line)
    (when (or (< arg 0) (not (eobp)))
      (transpose-lines arg))
    (forward-line -1)))

;; (defun custom/move-region (arg)
;;   "Move a region arg times up or down"
;;   (when (> (point) (mark))
;;     (exchange-point-and-mark))
;;   (let ((column (current-column))
;;     (text (delete-and-extract-region (point) (mark))))
;;     (forward-line arg)
;;     (move-to-column column 'force)
;;     (set-mark (point))
;;     (insert text)
;;     (exchange-point-and-mark)
;;     (setq deactivate-mark nil)))

(defun custom/move-region (arg)
  "Move a region arg times up or down"
  (if (> (point) (mark))
      (progn
        (beginning-of-line 2)
        (exchange-point-and-mark)
        (beginning-of-line))
    (progn
      (beginning-of-line)
      (exchange-point-and-mark)
      (if (not (= (current-column) 0)) (beginning-of-line 2))))
  (let ((text (delete-and-extract-region (point) (mark))))
    (forward-line arg)
    (set-mark (point))
    (insert text)
    (exchange-point-and-mark)
    (setq deactivate-mark nil)))

(defun custom/move-lines (arg)
  "Move a line or a region arg times up or down"
  (if (and mark-active transient-mark-mode)
      (custom/move-region arg)
    (custom/move-line arg)))

(defun custom/move-lines-up (arg)
  "Move a line or a region up"
  (interactive "p")
  (custom/move-lines (- arg)))

(defun custom/move-lines-down (arg)
  "Move a line or a region down"
  (interactive "p")
  (custom/move-lines arg))

;;; Other helpful functions

(defun reload-compile (&optional cc cflags)
  (interactive "MCompiler to use: \nMCompiler flags: ")
  (hooks/c-compilation cc cflags))
